import { VFSService } from '../vfs/vfs.service';
import { TSXComplianceChecker } from './TSXComplianceChecker';
import { ITypeEntity } from '../../../superType/types';

interface TypeValidationResult {
  hash: string;
  content: string;
}

interface FileSystemEntry {
  path: string;
  content: any;
  stats?: any;
}

/**
 * 验证并更新类型文件 - 后端版本
 * 严格按照前端参数顺序复刻 validateAndUpdateType 逻辑
 * 前端接口：validateAndUpdateType(vfs, path, content, options)
 */
export const validateAndUpdateType = async (
  vfs: VFSService,
  path: string,
  content: any,
  options: {
    existTypeEntity?: ITypeEntity;
    encoding?: string;
    mode?: number;
    flag?: string;
  } = {},
): Promise<TypeValidationResult> => {
  console.log('validateAndUpdateType (Backend): ', path);

  let existTypeEntity = options.existTypeEntity;

  let typeItem = typeof existTypeEntity === 'string' ? JSON.parse(existTypeEntity) : existTypeEntity;
  if (!typeItem) {
    typeItem = await handleNewTypeFile(vfs, path, content);
  }

  // 从文件内容中解析元数据（简化版本）
  const parsedMeta = parseTypeScriptMeta(content);
  console.log('parsedMeta: ', parsedMeta);

  // 根据文件路径确定类型
  const fileInfo = parseFileTypeFromPath(path);

  console.log('fileInfo: ', fileInfo);

  try {
    // 更新类型实体
    const updatedTypeItem = {
      ...typeItem,
      ...parsedMeta,
      update_time: Date.now(),
      // 根据文件内容更新相关字段
      ...(fileInfo.type && { type: fileInfo.type }),
      ...(fileInfo.name && { name: fileInfo.name }),
    };

    // 生成哈希
    const hash = generateHash(JSON.stringify(updatedTypeItem));

    return {
      hash,
      content: JSON.stringify(updatedTypeItem, null, 2),
    };
  } catch (error) {
    console.error('类型文件验证失败:', error);
    throw new Error(`类型文件验证失败: ${error.message}`);
  }
};

/**
 * 处理新建类型文件
 */
async function handleNewTypeFile(
  vfs: VFSService,
  path: string,
  content: any,
): Promise<TypeValidationResult> {
  console.log('创建新的类型文件:', path);

  try {
    const fileInfo = parseFileTypeFromPath(path);
    const parsedMeta = parseTypeScriptMeta(content);

    // 创建新的类型实体
    const newTypeItem: ITypeEntity = {
      _id: '', // 将在保存时生成
      name: fileInfo.name || path.split('/').pop()?.replace(/\.[^/.]+$/, ''),
      // @ts-ignore
      type: fileInfo.type || 'data',
      desc: parsedMeta.title || fileInfo.name || path.split('/').pop(),
      projectId: '', // 将由调用方设置
      create_time: Date.now(),
      update_time: Date.now(),
      userId: 0, // 将由调用方设置
      // 根据文件内容设置
      source: content,
      ...parsedMeta,
    };

    const hash = generateHash(JSON.stringify(newTypeItem));

    return {
      hash,
      content: JSON.stringify(newTypeItem, null, 2),
    };
  } catch (error) {
    console.error('创建新类型文件失败:', error);
    throw new Error(`创建新类型文件失败: ${error.message}`);
  }
}

/**
 * 从 TypeScript 代码中解析元数据 (JSDoc 注释)
 */
function parseTypeScriptMeta(content: string): {
  title?: string;
  intro?: string;
  methods?: string[];
  [key: string]: any;
} {
  const meta: any = {};

  // 查找文件顶部的 JSDoc 注释块
  const jsdocMatch = content.match(/^\s*\/\*\*([\s\S]*?)\*\//);
  if (!jsdocMatch) {
    return meta;
  }

  const commentContent = jsdocMatch[1];
  const lines = commentContent.split('\n').map((line) => line.trim().replace(/^\*\s?/, ''));

  let foundFirstTag = false;

  for (const line of lines) {
    if (!line) continue;

    // 处理 @tag 标签
    if (line.startsWith('@')) {
      foundFirstTag = true;

      // @methods 标签 - 云函数支持的 HTTP 方法
      const methodsMatch = line.match(/^@methods\s+(.+)$/);
      if (methodsMatch) {
        meta.methods = methodsMatch[1].split(',').map((m) => m.trim().toUpperCase());
        continue;
      }

      // @api 标签 - API 接口信息
      const apiMatch = line.match(/^@api\s+(\w+)\s+(.+)$/);
      if (apiMatch) {
        meta.api = {
          method: apiMatch[1],
          path: apiMatch[2],
        };
        continue;
      }

      // @title 标签
      const titleMatch = line.match(/^@title\s+(.+)$/);
      if (titleMatch) {
        meta.title = titleMatch[1];
        continue;
      }

      // @description 标签
      const descMatch = line.match(/^@description\s+(.+)$/);
      if (descMatch) {
        meta.desc = descMatch[1];
        continue;
      }

      continue;
    }

    // 如果还没有遇到第一个 @ 标签，则认为是描述内容
    if (!foundFirstTag) {
      if (meta.intro) {
        meta.intro += ' ' + line;
      } else {
        meta.intro = line;
      }
    }
  }

  return meta;
}

/**
 * 从文件路径解析文件类型
 */
function parseFileTypeFromPath(path: string): {
  type: string;
  name: string;
  category: string;
} {
  const cleanPath = path.startsWith('/') ? path.substring(1) : path;
  const parts = cleanPath.split('/');
  const fileName = parts[parts.length - 1];

  // 移除扩展名
  const nameWithoutExt = fileName.includes('.') ?
    fileName.substring(0, fileName.lastIndexOf('.')) : fileName;

  // 确定类型和分类
  let type = 'data';
  let category = 'global';

  if (cleanPath.includes('/actions/') || cleanPath.includes('/utils/')) {
    type = 'action';
    category = 'actions';
  } else if (cleanPath.includes('/models/') || cleanPath.includes('/data/')) {
    type = 'data';
    category = 'models';
  } else if (cleanPath.includes('/apis/')) {
    type = 'api';
    category = 'apis';
  } else if (cleanPath.includes('/code/')) {
    type = 'code';
    category = 'code';
  }

  return {
    type,
    name: nameWithoutExt,
    category,
  };
}

/**
 * 生成哈希
 */
function generateHash(content: string): string {
  let hash = 0;
  for (let i = 0; i < content.length; i++) {
    const char = content.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash = hash & hash; // 转换为32位整数
  }
  return Math.abs(hash).toString(16);
}